package com.liduanwei.update.app;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.liduanwei.update.app.*;
import com.liduanwei.update.entity.RemoteAppInfo;
import com.liduanwei.update.quartz_job.CheckNewVersionJob;
import com.liduanwei.update.util.*;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

public class AppService {

    private static final String UPDATER_SERVER_HOST = "http://mm1.jinrustar.com:8533";

    private static SelfVersionChecker selfVersionChecker = new SelfVersionChecker();
    private static MachineHttpServiceVersionChecker machineHttpServiceVersionChecker = new MachineHttpServiceVersionChecker();
    private static MachineVersionChecker machineVersionChecker = new MachineVersionChecker();
    private static MachineUIVersionChecker machineUIVersionChecker = new MachineUIVersionChecker();
    private static OtherFilesVersionChecker otherFilesVersionChecker = new OtherFilesVersionChecker();

    private static AbstractChecker[] versionCheckers = {
            machineHttpServiceVersionChecker,
            machineUIVersionChecker,
            machineVersionChecker,
            otherFilesVersionChecker,
            selfVersionChecker
    };

    public static void updateCurrentVersionToServer(Map<String, String> data) throws IOException {
        final String updateCurrentVersionUrl = "http://mm1.jinrustar.com:8533/version/current/" + Constants.MACHINE_ID + "/update";
        HttpURLConnection urlConnection = (HttpURLConnection) new URL(updateCurrentVersionUrl).openConnection();
        urlConnection.setDoOutput(true);
        OutputStream outputStream = urlConnection.getOutputStream();

        String paramsStr = generateParamsFromMap(data);

        PrintUtil.Companion.print(paramsStr);

        outputStream.write(paramsStr.getBytes());
        outputStream.flush();
        /*todo*/
        InputStream inputStream = urlConnection.getInputStream();
        byte[] resp = FileUtil.readInputStream(inputStream);

        PrintUtil.Companion.print(new String(resp));
    }

    private static String generateParamsFromMap(Map<String, String> data) {
        Set<String> keys = data.keySet();

        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            sb.append("&").append(key).append("=").append(data.get(key));
        }
        return sb.toString();
    }


    public static void startSchedule() {
        try {
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            Trigger trigger = newTrigger().withIdentity("trigger1", "group1") //定义name/group
                    .startNow()
                    .withSchedule(simpleSchedule()
                            .withIntervalInSeconds(2 * 60) //每隔固定间隔秒执行一次
                            .repeatForever()) //一直执行
                    .build();

            JobDetail job = newJob(CheckNewVersionJob.class)
                    .withIdentity("job1", "group1")
                    .usingJobData("name", "check new version")/*job附带数据*/
                    .build();

            scheduler.scheduleJob(job, trigger);

            scheduler.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void checkNewestVersion(String machineId, boolean force) {
        final String newVersionUrl = UPDATER_SERVER_HOST + "/version/newest/" + machineId + "/view";

        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(newVersionUrl).openConnection();
            InputStream in = connection.getInputStream();
            byte[] bytes = FileUtil.readInputStream(in);

            String resp = new String(bytes);


            JSONObject jsonResponse = (JSONObject) JSON.parse(resp);

            /*生成remoteAppInfo*/

            JSONObject data = jsonResponse.getJSONObject("data");
            if (data != null) {
                String httpVersionName = data.getString("httpServiceVersionName");
                int httpVersionCode = data.getIntValue("httpServiceVersionCode");
                String httpServiceVersionUrl = data.getString("httpServiceVersionUrl");


                String machineVersionName = data.getString("machineVersionName");
                int machineVersionCode = data.getIntValue("machineVersionCode");
                String machineVersionUrl = data.getString("machineVersionUrl");


                String uiVersionName = data.getString("uiVersionName");
                int uiVersionCode = data.getIntValue("uiVersionCode");
                String uiVersionUrl = data.getString("uiVersionUrl");

                String otherFilesVersionName = data.getString("otherFilesVersionName");
                int otherFilesVersionCode = data.getIntValue("otherFilesVersionCode");
                String otherFilesVersionUrl = data.getString("otherFilesVersionUrl");


                String selfVersionName = data.getString("selfVersionName");
                int selfVersionCode = data.getIntValue("selfVersionCode");
                String selfVersionUrl = data.getString("selfVersionUrl");

                if (machineHttpServiceVersionChecker.getLastRemoteAppInfo() == null || machineHttpServiceVersionChecker.getLastRemoteAppInfo().getVersionCode() != httpVersionCode) {
                    machineHttpServiceVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(httpServiceVersionUrl, httpVersionCode, httpVersionName));
                }

                if (machineVersionChecker.getLastRemoteAppInfo() == null || machineVersionChecker.getLastRemoteAppInfo().getVersionCode() != machineVersionCode) {
                    machineVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(machineVersionUrl, machineVersionCode, machineVersionName));
                }
                if (machineUIVersionChecker.getLastRemoteAppInfo() == null || machineUIVersionChecker.getLastRemoteAppInfo().getVersionCode() != uiVersionCode) {
                    machineUIVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(uiVersionUrl, uiVersionCode, uiVersionName));
                }

                if (otherFilesVersionChecker.getLastRemoteAppInfo() == null || otherFilesVersionChecker.getLastRemoteAppInfo().getVersionCode() != otherFilesVersionCode) {
                    otherFilesVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(otherFilesVersionUrl, otherFilesVersionCode, otherFilesVersionName));
                }
                if (selfVersionChecker.getLastRemoteAppInfo() == null || selfVersionChecker.getLastRemoteAppInfo().getVersionCode() != selfVersionCode) {
                    selfVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(selfVersionUrl, selfVersionCode, selfVersionName));
                }

                Arrays.asList(versionCheckers).forEach(e -> e.start(force));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void checkNewestVersion2(String machineId, boolean force) {
        final String newVersionUrl = UPDATER_SERVER_HOST + "/version/newest/" + machineId + "/version/check?" +
                "httpServiceVersionCode=" + machineHttpServiceVersionChecker.loadCurrentAppInfo().getVersionCode() +
                "&machineVersionCode=" + machineVersionChecker.loadCurrentAppInfo().getVersionCode() +
                "&uiVersionCode=" + machineUIVersionChecker.loadCurrentAppInfo().getVersionCode() +
                "&otherFilesVersionCode=" + otherFilesVersionChecker.loadCurrentAppInfo().getVersionCode() +
                "&selfVersionCode=" + selfVersionChecker.loadCurrentAppInfo().getVersionCode();

        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(newVersionUrl).openConnection();
            InputStream in = connection.getInputStream();
            byte[] bytes = FileUtil.readInputStream(in);

            String resp = new String(bytes);


            PrintUtil.Companion.print("=====" + resp);
            JSONObject jsonResponse = (JSONObject) JSON.parse(resp);


            /*生成remoteAppInfo*/

            JSONArray data = jsonResponse.getJSONArray("data");
            if (data != null) {
                for (Object obj : data) {
                    JSONObject jsonObject = (JSONObject) obj;
                    String type = jsonObject.getString("type");
                    int versionCode = jsonObject.getIntValue("versionCode");
                    String versionName = jsonObject.getString("versionName");
                    String versionUrl = jsonObject.getString("versionUrl");

                    if ("httpServiceVersion".equals(type)) {
                        machineHttpServiceVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(versionUrl, versionCode, versionName));
                    } else if ("machineVersion".equals(type)) {
                        machineVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(versionUrl, versionCode, versionName));
                    } else if ("uiVersion".equals(type)) {
                        machineUIVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(versionUrl, versionCode, versionName));
                    } else if ("otherFilesVersion".equals(type)) {
                        otherFilesVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(versionUrl, versionCode, versionName));
                    } else if ("selfVersion".equals(type)) {
                        selfVersionChecker.setLastRemoteAppInfo(new RemoteAppInfo(versionUrl, versionCode, versionName));
                    }
                }

                Arrays.asList(versionCheckers).forEach(e -> e.start(force));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static public String getMachineId() {

        String machineInfoFilePath;
        if (OSUtil.Companion.isLinux()) {
            machineInfoFilePath = "/media/yao/xxx/jinru/Updater/updater_machine_info.properties";
        } else {
            machineInfoFilePath = "./updater_machine_info.properties";
        }
        return PropertiesUtil.Companion.loadProperties(machineInfoFilePath).getProperty("machine_id");
    }

    static public void startCheckNewVersionForce() {
        checkNewestVersion2(Constants.MACHINE_ID, true);
    }

    public static boolean hasDownloadingTask() {
        for (AbstractChecker checker : versionCheckers) {
            if (checker.isDownloading()) {
                return true;
            }
        }
        return false;
    }

    public static void updateVersionToServer(Map<String, String> data) {
        try {
            AppService.updateCurrentVersionToServer(data);
            PrintUtil.Companion.print("=========更新版本信息...==============");
        } catch (IOException e) {
            PrintUtil.Companion.print("=========更新版本信息异常...=" + e.getMessage());
            e.printStackTrace();
        }
    }
}
